package serialport;

import android.os.Environment;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import beans.CabinetInfoBean;
import beans.CabinetInfoParentBean;
import beans.ScmSerialPortBean;
import constants.Constants;
import constants.HandlerConstant;
import customhandler.MyHandler;
import singleton.SingletonClass;
import utils.CRCUtils;
import utils.DigitalTrans;
import utils.FormateUtils;
import utils.ObjectSaveUtil;
import utils.TimeUtil;
import utils.ToastUtil;

/**
 * Created by Administrator on 2018/5/18.
 */

public class ReceiveScmInfo {
    private MyHandler allHandler;
    public String increase = "", decrease = "";
    public ByteArrayOutputStream baos;
    public List<byte[]> list = new ArrayList<>();
    private String address1;
    private ScmSerialPortBean bean;

    public ReceiveScmInfo(ScmSerialPortBean bean) {
        this.bean = bean;
        baos = new ByteArrayOutputStream();
        allHandler = SingletonClass.getSingleton(MyHandler.class);
    }

    //根据接收到命令类型进行处理
    public void readAccordCommandType(byte[] bytes) {
        bean.setCount(0);
        int packageCount = bean.getPackageCount();
        bean.setPackageCount(++packageCount);
        //收到帧的命令类型
        int commandType = bytes[19] & 0xFF;
        //总包数
        int totalCount = bytes[5] & 0xFF;
        //当前包数
        int currentCount = bytes[6] & 0xFF;
        switch (commandType) {
            case 0x10:
                Log.e("BBB", "10");
                //数据域长度为0,不做任何解析,只要判断是否是01的应答帧
                removeMessage(HandlerConstant.SERIAL_PORT_REPEAT);
                break;
            case 0x20:
                //数据域长度为0,不做任何解析,只要判断是否是02的应答帧
                removeMessage(HandlerConstant.SERIAL_PORT_REPEAT);
                break;
            case 0x03:
                Log.e("BBB", "03");
                allHandler.sendEmptyMessage(HandlerConstant.OPEN_DOOR);
                //下位机开门时,发送到上位机,上位机接收到之后,往下位机发送应答帧
                writeData(bytes, "300000", false);
                break;
            case 0x04:
                Log.e("BBB", "04");
                //下位机关门时,发送到上位机,上位机接收到之后,往下位机发送应答帧,并做关门之后的相应处理
                writeData(bytes, "400000", false);
                Message message = allHandler.obtainMessage();
                bean.setCount(bean.getCount() + 1);
                //若isSCMNumber为true则是柜子编号的操作(注意,编号的时候,不会发送应答帧,因为不知道单片机地址)
                if (bean.isCabinetCode()) {
                    bean.setCabinetCode(false);
                    message.obj = DigitalTrans.toHexStringByte(bytes[13]) + DigitalTrans.toHexStringByte(bytes[14]) + DigitalTrans.toHexStringByte(bytes[15]) + DigitalTrans.toHexStringByte(bytes[16]) + DigitalTrans.toHexStringByte(bytes[17]) + DigitalTrans.toHexStringByte(bytes[18]);
                    message.what = HandlerConstant.SCM_NUMBER_CLOSE_DOOR;
                } else {
                    message.obj = bean.getSelectCabinet();
                    message.what = HandlerConstant.CLOSE_DOOR;
                }
                allHandler.sendMessage(message);
                break;
            case 0x50:
                //下位机向上位机上传设置值(是对上位机05的应答帧)
                removeMessage(HandlerConstant.SERIAL_PORT_REPEAT);
                Message message2 = allHandler.obtainMessage();
                //解析单片机的设置值(天线选择4位,功率设置2位,频段选择1位,扫描时间1位)
                Log.e("AAA", "readAccordCommandType: " + DigitalTrans.toHexString(bytes) );
//                if (bytes.length <= 30){
                    message2.obj = DigitalTrans.toHexStringByte(bytes[22]) + DigitalTrans.toHexStringByte(bytes[23]) + DigitalTrans.toHexStringByte(bytes[24]) + DigitalTrans.toHexStringByte(bytes[25]) + DigitalTrans.toHexStringByte(bytes[26]) + DigitalTrans.toHexStringByte(bytes[27]) + DigitalTrans.toHexStringByte(bytes[28]) + DigitalTrans.toHexStringByte(bytes[29]);
//                }else {
//                    message2.obj = DigitalTrans.toHexStringByte(bytes[22]) + DigitalTrans.toHexStringByte(bytes[23]) + DigitalTrans.toHexStringByte(bytes[24]) + DigitalTrans.toHexStringByte(bytes[25]) + DigitalTrans.toHexStringByte(bytes[26]) + DigitalTrans.toHexStringByte(bytes[27]) + DigitalTrans.toHexStringByte(bytes[28]) + DigitalTrans.toHexStringByte(bytes[29])+ DigitalTrans.toHexStringByte(bytes[30])+ DigitalTrans.toHexStringByte(bytes[31])+ DigitalTrans.toHexStringByte(bytes[32])+ DigitalTrans.toHexStringByte(bytes[33])+ DigitalTrans.toHexStringByte(bytes[34]);
//                }
                message2.what = HandlerConstant.GET_CABINET_SET_SUCCESS;
                allHandler.sendMessage(message2);
                break;
            case 0x60:
                //下位机收到设置命令时的应答帧
                removeMessage(HandlerConstant.SERIAL_PORT_REPEAT);
                allHandler.sendEmptyMessage(HandlerConstant.SET_CABINET_SUCCESS);
                break;
            case 0x70:
                //下位机收到选中信号时的应答帧
                removeMessage(HandlerConstant.SERIAL_PORT_REPEAT);
                break;
            case 0x08:
                //判断是否是异常开门
                String s = DigitalTrans.toHexStringByte(bytes[26]);
                Log.e("BaseActivity", "readAccordCommandType: " + s);
                //正常开门
                if (s.startsWith("0")) {
                    dealReturnRfidCode("800000", bean.getPackageCount(), totalCount, bytes, true);
                } else if (s.startsWith("8")) {  //异常开门
                    dealAbnormalGoods("800000", bean.getPackageCount(), totalCount, bytes);
                }
                break;
            case 0x90:
                removeMessage(HandlerConstant.SERIAL_PORT_REPEAT);
                //这里是单片机回复的应答帧,上位机无须再发应答帧
                Log.e("TAG", "readAccordCommandType: " + bean.getPackageCount() + "  " + totalCount );
                dealReturnRfidCode("00", bean.getPackageCount(), totalCount,  bytes, false);
                break;
            case 0x0E:
                String m = DigitalTrans.toHexStringByte(bytes[22]);
//                58 4C 4B 4A 01 01 01 12 34 56 78 90 AB 01 18 01 08 25 09 0E 00 01 01 D0 CB
                String type = m.substring(1, m.length());
                Log.e("AAA", "type: " + type );
                if (m.startsWith("0")) {
                    //下位机主动发送的错误报告
                    writeData(bytes, "E00000", false);
                    if (type.equals("1") || type.equals("2") || type.equals("6")) { // 没有RFID增减量
                        if (type.equals("6")) {
                            String errorType = DigitalTrans.toHexStringByte(bytes[23]);
                            Log.e("AAA", "errorType: " + errorType );
                            Message message1 = allHandler.obtainMessage();
                            message1.obj = errorType;
                            message1.what = HandlerConstant.SERIALPORT_ERROR;
                            allHandler.sendMessage(message1);
                        }
                        Message message1 = allHandler.obtainMessage();
                        message1.obj = Constants.INCREASE_DECREASE_SPLIT;
                        message1.what = HandlerConstant.SCAN_COMPLETE_ERROR;
                        allHandler.sendMessage(message1);
                    }
                    if (!type.equals("6")){
                        int rfidSum = Integer.parseInt(DigitalTrans.toHexStringByte(bytes[23]) + DigitalTrans.toHexStringByte(bytes[24]), 16);
                        Log.e("AAA", "readAccordCommandType: " + rfidSum );
                        Message message1 = allHandler.obtainMessage();
                        message1.obj = rfidSum;
                        message1.what = HandlerConstant.RFID_SUM;
                        allHandler.sendMessage(message1);
                    }
                } else if (m.startsWith("8")) {
                    //异常开门时
                    address1 = DigitalTrans.toHexStringByte(bytes[13]) + DigitalTrans.toHexStringByte(bytes[14]) + DigitalTrans.toHexStringByte(bytes[15]) + DigitalTrans.toHexStringByte(bytes[16]) + DigitalTrans.toHexStringByte(bytes[17]) + DigitalTrans.toHexStringByte(bytes[18]);
                    writeData(bytes, "E00000", false);
                }
                break;

            //下位机对上位机轮回的应答帧
            case 0xA0:
                if (allHandler.hasMessages(HandlerConstant.ROLL)) {
                    allHandler.removeMessages(HandlerConstant.ROLL);
                }
                //此时应该获取下位机的地址,以此判断是哪台柜子
                Message message3 = allHandler.obtainMessage();
                message3.obj = DigitalTrans.toHexStringByte(bytes[13]) + DigitalTrans.toHexStringByte(bytes[14]) + DigitalTrans.toHexStringByte(bytes[15]) + DigitalTrans.toHexStringByte(bytes[16]) + DigitalTrans.toHexStringByte(bytes[17]) + DigitalTrans.toHexStringByte(bytes[18]);
                message3.what = HandlerConstant.ROLL_SUCCESS;
                allHandler.sendMessage(message3);
                break;
        }
    }

    //处理单片机返回的Rfid数据
    public void dealReturnRfidCode(String resondCode, int currentCount, int totalCount, byte[] bytes, boolean isWriteResponse) {
        if (currentCount == 1) {
            baos.reset();
            increase = "";
            decrease = "";
            list.clear();
        }

        list.add(bytes);
        //先发送应答,在处理数据
        if (currentCount == totalCount) {
            removeMessage(HandlerConstant.SERIAL_PORT_REPEAT);
            if (isWriteResponse) {
                writeData(bytes, resondCode, false);
            }else {
                bean.setPackageCount(0);
            }
            //数据域长度
            int dataLength = Integer.parseInt(DigitalTrans.toHexStringByte(bytes[20]) + DigitalTrans.toHexStringByte(bytes[21]), 16);
            //数据域之中除开RFIDCODE之外的字节为6,大于6,则必然有RFIDCODE
            if (dataLength > 6) {
                for (int i = 0; i < list.size(); i++) {
                    //减去两位校验位和RFIDCode之前的固定的字节
                    baos.write(list.get(i), 27, list.get(i).length - 29);
                }
                byte[] rfidByte = baos.toByteArray();
                int increaseCount = Integer.parseInt(DigitalTrans.toHexStringByte(bytes[22]) + DigitalTrans.toHexStringByte(bytes[23]), 16);
//                int decreaseCount = Integer.parseInt(DigitalTrans.toHexStringByte(bytes[24]) + DigitalTrans.toHexStringByte(bytes[25]), 16);
                String rfidCodes = DigitalTrans.toHexString(rfidByte);
                increase = getIncrease(rfidCodes, Constants.RFID_LENGTH, increaseCount);
                decrease = getDecrease(rfidCodes, Constants.RFID_LENGTH, increaseCount);
            }
            //上位机收到下位机的增量,减量时,向下位机发送应答帧
            Message message1 = allHandler.obtainMessage();
            message1.obj = increase + Constants.INCREASE_DECREASE_SPLIT + decrease;
            //盘点的时候,是false,发送柜号,用于UI显示
            if (!isWriteResponse) {
                message1.arg1 = bean.getSelectCabinet();
            }
            message1.what = HandlerConstant.SCAN_COMPLETE;
            allHandler.sendMessage(message1);
        }else {
            // 发送延迟消息，等待第二个包
            sendEmptyMessageDelayed(HandlerConstant.SERIAL_PORT_REPEAT, Constants.REPART_DELAY);
        }
    }

    //处理单片机返回的Rfid数据（非正常开门）
    public void dealAbnormalGoods(String responseCode, int currentCount, int totalCount, byte[] bytes) {
        if (currentCount == 1) {
            baos.reset();
            increase = "";
            decrease = "";
            list.clear();
        }

        list.add(bytes);
        //先发送应答,在出处理数据
        if (currentCount == totalCount) {
            writeData(bytes, responseCode, false);
            //数据域长度
            int dataLength = Integer.parseInt(DigitalTrans.toHexStringByte(bytes[20]) + DigitalTrans.toHexStringByte(bytes[21]), 16);
            //数据域之中除开RFIDCODE之外的字节为6,大于6,则必然有RFIDCODE
            if (dataLength > 6) {
                for (int i = 0; i < list.size(); i++) {
                    //减去两位校验位和RFIDCode之前的固定的字节
                    baos.write(list.get(i), 27, list.get(i).length - 29);
                }
                byte[] rfidByte = baos.toByteArray();
                int increaseCount = Integer.parseInt(DigitalTrans.toHexStringByte(bytes[22]) + DigitalTrans.toHexStringByte(bytes[23]), 16);
                String rfidCodes = DigitalTrans.toHexString(rfidByte);
                increase = getIncrease(rfidCodes, Constants.RFID_LENGTH, increaseCount);
                decrease = getDecrease(rfidCodes, Constants.RFID_LENGTH, increaseCount);
                if (!TextUtils.isEmpty(increase) || !TextUtils.isEmpty(decrease)) {
                    int cabinetInfoId = 0;
                    CabinetInfoParentBean cabinetInfoParentBean = (CabinetInfoParentBean) ObjectSaveUtil.readObject(bean.getmContext(), Constants.CABINETINFO_PARENT_BEAN, Constants.CABINETINFO_PARENT_BEAN);
                    if (cabinetInfoParentBean != null) {
                        List<CabinetInfoBean> cabinetInfoBeanList = cabinetInfoParentBean.getCabinetInfoBeanList();

                        for (int i = 0; i < cabinetInfoBeanList.size(); i++) {
                            if (address1.equals(cabinetInfoBeanList.get(i).getCabinetCode())) {
                                cabinetInfoId = cabinetInfoBeanList.get(i).getID();
                                break;
                            }
                        }

                    }
                    if (!TextUtils.isEmpty(increase)) {
                        //8放入
                        AbnoramlGoodsDeal.operaGoodsDetails(FormateUtils.getRfidCodes(increase), String.valueOf(cabinetInfoId), 8, bean.getmContext(), bean.getSelectCabinet());
                    }
                    if (!TextUtils.isEmpty(decrease)) {
                        //7取出
                        AbnoramlGoodsDeal.operaGoodsDetails(FormateUtils.getRfidCodes(decrease), String.valueOf(cabinetInfoId), 7, bean.getmContext(), bean.getSelectCabinet());
                    }
                }
            }
        }
    }

    //获取归还的RFID
    public static String getIncrease(String hexString, int rfidLength, int increaseCount) {
        //得到归还的RFID的BCD码
        if (hexString.length() >= rfidLength * increaseCount) {
            return hexString.substring(0, rfidLength * increaseCount);
        } else {
            return "";
        }
    }

    // 获取取出的RFID
    public static String getDecrease(String hexString, int rfidLength, int increaseCount) {
        //得到取出的RFID的BCD码
        if (hexString.length() >= rfidLength * increaseCount) {
            return hexString.substring(rfidLength * increaseCount, hexString.length());
        } else {
            return "";
        }
    }

    public void writeData(byte[] bytes, String hexString, boolean isRepeat) {
        try {
            bean.setPackageCount(0);
            address1 = FormateUtils.getAddress(bytes);
            if (!TextUtils.isEmpty(address1)) {
                bean.setSerialPortString(hexString);

                String s = "010101" + address1 + Constants.ANDROID_ADDRESS + hexString;
                byte[] b = DigitalTrans.hexStringToByteArray(s);
                char crc = CRCUtils.getCrc(b, (byte) b.length);

                int i = (int) crc;

                String check = DigitalTrans.hexNumberFormat(i, 4);


//                saveToFile(address1 + Constants.ANDROID_ADDRESS + "    " + hexString + "    " + check);
//                bean.getmOutputStream().write(DigitalTrans.hexStringToByteArray("584C4B4A010101" + address1 + Constants.ANDROID_ADDRESS + hexString + check));

                saveToFile(address1 + Constants.ANDROID_ADDRESS + "    " + hexString );
                bean.getmOutputStream().write(DigitalTrans.hexStringToByteArray("584C4B4A010101" + address1 + Constants.ANDROID_ADDRESS + hexString ));

                if (isRepeat) {
                    sendEmptyMessageDelayed(HandlerConstant.SERIAL_PORT_REPEAT, Constants.REPART_DELAY);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    void removeMessage(int i) {
        bean.getSerialPortData().removeMessage(i);
    }

    void sendEmptyMessageDelayed(int what, long delayMillis) {
        bean.getSerialPortData().sendEmptyFrameMessageDelayed(what, delayMillis);
    }


    private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

    public void saveToFile(String receiveData) {
        StringBuffer sb = new StringBuffer();
        try {
            if (Environment.getExternalStorageState().equals(
                    Environment.MEDIA_MOUNTED)) {
                String time = formatter.format(new Date());
                sb.append(time);
                sb.append("  --send begin--:  ");
                sb.append(receiveData);
                sb.append("  --send end--;  ");
                sb.append("\r\n");
                String fileName = TimeUtil.getYear() + "-" + (TimeUtil.getMonth() + 1) + "-" + TimeUtil.getDay() + ".log";
                String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/serialport/";
                File dir = new File(path);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                FileOutputStream fos = new FileOutputStream(path + fileName, true);
                fos.write(sb.toString().getBytes());
                fos.flush();
                fos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
